<?php
namespace app\models;

use Yii;
use yii\base\Model;

/**
 * 账号设置
 *
 * Class UserProfile
 * @package app\models
 */
class UserProfile extends Model
{
    public $avatar_fid;
    public $nickname;
    public $gender;
    public $birthday;
    public $old_mobile;
    public $mobile;
    public $email;
    public $new_password;
    public $confirm_password;
    public $vcode;
    public $goon;
    
    /**
     * @inheritdoc
     */
    public function scenarios()
    {
        return [
            'basic'=>['avatar_fid', 'nickname', 'gender', 'birthday'],
            'change_mobile'=>['old_mobile', 'vcode'], // 修改手机
            'change_mobile_with_email'=>['old_mobile', 'email', 'vcode'], // 通过认证邮箱修改手机
            'verify_mobile'=>['goon', 'mobile', 'vcode'], // 认证新手机
            'set_email'=>['vcode', 'email'], // 设置认证邮箱
            'verify_email'=>['vcode'], // 认证邮箱
            'change_password'=>['new_password', 'confirm_password', 'vcode'], // 修改密码
        ];
    }
    
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            // 基本资料修改 开始
            [['nickname'], 'required', 'on'=>'basic'],
            [['gender', 'birthday'], 'safe', 'on'=>'basic'],
            // 基本资料修改 结束
            // 旧手机验证 开始
            [['old_mobile', 'vcode'], 'required', 'on'=>'change_mobile'],
            // 旧手机验证 结束
            // 认证邮箱验证 开始
            [['old_mobile', 'email', 'vcode'], 'required', 'on'=>'change_mobile_with_email'],
            // 认证邮箱验证 结束
            // 认证新手机 开始
            [['mobile', 'vcode'], 'required', 'on'=>'verify_mobile'],
            // 认证新手机 结束
            // 设置邮箱 开始
            ['vcode', 'required', 'on'=>'set_email'],
            ['email', 'required', 'on'=>'set_email'],
            ['email', 'email', 'on'=>'set_email'],
            // 设置邮箱 结束
            // 认证邮箱 开始
            ['vcode', 'required', 'on'=>'verify_email'],
            ['vcode', 'checkVerifyEmailVcode', 'on'=>'verify_email'],
            // 认证邮箱 结束
            // 修改密码 开始
            [['new_password', 'confirm_password', 'vcode'], 'required', 'on'=>'change_password'],
            [['new_password', 'confirm_password'], function() {
                if ($this->new_password != $this->confirm_password) {
                    $this->addError('new_password', '两次输入密码不同。');
                }
            }, 'on'=>'change_password'],
            ['vcode', function() {
                /* @var $user User */
                $user = Yii::$app->user->identity;
                if (!Sms::checkCode($user->mobile, Sms::TYPE_CHANGE_PASSWORD, $this->vcode)) {
                    $this->addError('vcode', '验证码错误。');
                }
            }, 'on'=>'change_password'],
            // 修改密码 结束
            [['mobile', 'email'], 'unique', 'targetClass'=>User::className(), 'filter'=>function($query) {/* @var $query \yii\db\Query */$query->andWhere(['<>', 'id', Yii::$app->user->id])->andWhere(['<>', 'status', User::STATUS_DELETED]);return $query;}],
        ];
    }
    
    /**
     * 保存用户基本资料
     * @return boolean
     */
    public function saveBasic()
    {
        if (!$this->validate()) {
            return false;
        }
        $user = User::findOne(Yii::$app->user->id);
        $user->avatar_fid = $this->avatar_fid;
        $user->nickname = $this->nickname;
        if (!$user->save()) {
            $this->addErrors($user->errors);
            return false;
        }
        Yii::$app->user->setIdentity($user);
        return true;
    }
    
    /**
     * 旧手机验证
     * @return boolean
     */
    public function changeMobile()
    {
        if (!$this->validate()) {
            return false;
        }
        /* @var $user User */
        $user = Yii::$app->user->identity;
        if ($user->mobile != $this->old_mobile) {
            $this->addError('old_mobile', '原手机号码错误。');
            return false;
        }
        if (!Sms::checkCode($this->old_mobile, Sms::TYPE_VERIFY, $this->vcode)) {
            $this->addError('vcode', '验证码错误。');
            return false;
        }
        $this->goon = 'mobile:' . Yii::$app->security->generatePasswordHash($this->old_mobile);
        return true;
    }
    
    /**
     * 认证邮箱验证
     * @return boolean
     */
    public function changeMobileWithEmail()
    {
        if (!$this->validate()) {
            return false;
        }
        /* @var $user User */
        $user = Yii::$app->user->identity;
        if ($this->old_mobile != $user->mobile) {
            $this->addError('old_mobile', '原手机号码错误。');
            return false;
        }
        if ($this->email != $user->email) {
            $this->addError('email', '认证邮箱错误。');
            return false;
        }
        if (!$this->checkVerifyEmailVcode('vcode', '')) {
            return false;
        }
        $this->goon = 'email:' . Yii::$app->security->generatePasswordHash($this->email);
        return true;
    }
    
    /**
     * 认证新手机
     * @return boolean
     */
    public function verifyMobile()
    {
        if (!$this->validate()) {
            return false;
        }
        /* @var $user User */
        $user = Yii::$app->user->identity;
        $goon = false;
        if (preg_match('/^mobile:.*$/', $this->goon)) {
            if (Yii::$app->security->validatePassword($user->mobile, substr($this->goon, 7))) {
                $goon = true;
            }
        }
        if (preg_match('/^email:.*$/', $this->goon)) {
            if (Yii::$app->security->validatePassword($user->email, substr($this->goon, 6))) {
                $goon = true;
            }
        }
        if (!$goon) {
            $this->addError('mobile', '您必须使用旧手机或验证邮箱验证后才能设置新号码。');
            return false;
        }
        if (!Sms::checkCode($this->mobile, Sms::TYPE_VERIFY, $this->vcode)) {
            $this->addError('vcode', '验证码错误。');
            return false;
        }
        $user = User::findOne(Yii::$app->user->id);
        $user->mobile = $this->mobile;
        if (!$user->save()) {
            $this->addErrors($user->errors);
            return false;
        }
        Yii::$app->user->setIdentity($user);
        return true;
    }
    
    /**
     * 设置邮箱
     * @return boolean
     */
    public function setEmail()
    {
        if (!$this->validate()) {
            return false;
        }
        /* @var $user User */
        $user = Yii::$app->user->identity;
        if (!Sms::checkCode($user->mobile, Sms::TYPE_VERIFY, $this->vcode)) {
            $this->addError('vcode', '验证码错误。');
            return false;
        }
        $vcode = Yii::$app->security->generateRandomString(6);
        /* @var $mailer \yii\swiftmailer\Mailer */
        $mailer = Yii::$app->mailer;
        /* @var $transport \Swift_SmtpTransport */
        $transport = $mailer->getTransport();
        $r = Yii::$app->mailer->compose()
        ->setTo($this->email)
        ->setFrom([$transport->getUsername() => Yii::$app->params['companyName']])
        ->setSubject(Yii::$app->params['companyName'] . '邮箱验证码')
        ->setTextBody('认证邮箱验证码：' . $vcode)
        ->send();
        if (!$r) {
            $this->addError('email', '发送邮件失败。');
            return false;
        }
        UserConfig::setConfig(Yii::$app->user->id, UserConfig::VERIFY_EMAIL, $this->email);
        UserConfig::setConfig(Yii::$app->user->id, UserConfig::VERIFY_EMAIL_VCODE, $vcode);
        return true;
    }
    
    /**
     * 检查认证邮箱验证码
     * @param string $attribute
     * @param mixed $params
     * @return boolean
     */
    public function checkVerifyEmailVcode($attribute, $params)
    {
        $_vcode = UserConfig::getConfig(Yii::$app->user->id, UserConfig::VERIFY_EMAIL_VCODE);
        if (empty($_vcode)) {
            $this->addError($attribute, '没有发送过验证码。');
            return false;
        }
        if (strtoupper($this->vcode) != strtoupper($_vcode)) {
            $this->addError($attribute, '验证码错误。');
            return false;
        }
        return true;
    }
    
    /**
     * 认证邮箱
     * @return boolean
     */
    public function verifyEmail()
    {
        if (!$this->validate()) {
            return false;
        }
        $user = User::findOne(Yii::$app->user->id);
        $user->email = UserConfig::getConfig(Yii::$app->user->id, UserConfig::VERIFY_EMAIL);
        if (!$user->save()) {
            $this->addErrors($user->errors);
            return false;
        }
        Yii::$app->user->setIdentity($user);
        return true;
    }
    
    /**
     * 修改登录密码
     * @return boolean
     */
    public function changePassword()
    {
        if (!$this->validate()) {
            return false;
        }
        $user = User::findOne(Yii::$app->user->id);
        $user->password = Yii::$app->security->generatePasswordHash($this->new_password);
        if (!$user->save()) {
            $this->addErrors($user->errors);
            return false;
        }
        Yii::$app->user->setIdentity($user);
        return true;
    }
}
